home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Info-Mac 4
/
Info_Mac IV CD-ROM (Pacific HiTech Inc.)(August 1994).iso
/
Development
/
Source
/
POVSRC
/
SOURCE
/
OBJECTS.C
< prev
next >
Wrap
Text File
|
1993-10-28
|
8KB
|
380 lines
/****************************************************************************
* objects.c
*
* This module implements the methods for objects and composite objects.
*
* from Persistence of Vision Raytracer
* Copyright 1993 Persistence of Vision Team
*---------------------------------------------------------------------------
* NOTICE: This source code file is provided so that users may experiment
* with enhancements to POV-Ray and to port the software to platforms other
* than those supported by the POV-Ray Team. There are strict rules under
* which you are permitted to use this file. The rules are in the file
* named POVLEGAL.DOC which should be distributed with this file. If
* POVLEGAL.DOC is not available or for more info please contact the POV-Ray
* Team Coordinator by leaving a message in CompuServe's Graphics Developer's
* Forum. The latest version of POV-Ray may be found there as well.
*
* This program is based on the popular DKB raytracer version 2.12.
* DKBTrace was originally written by David K. Buck.
* DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
*
*****************************************************************************/
#include "frame.h"
#include "vector.h"
#include "povproto.h"
extern long Bounding_Region_Tests, Bounding_Region_Tests_Succeeded;
extern long Clipping_Region_Tests, Clipping_Region_Tests_Succeeded;
extern unsigned int Options;
extern long Istack_overflows;
extern int Number_of_istacks;
extern int Max_Intersections;
extern ISTACK *free_istack;
int Intersection (Ray_Intersection, Object, Ray)
INTERSECTION *Ray_Intersection;
OBJECT *Object;
RAY *Ray;
{
ISTACK *Depth_Stack;
INTERSECTION *Local;
DBL Closest = HUGE_VAL;
if (Object == NULL)
return (FALSE);
if(!Ray_In_Bounds (Ray,Object->Bound))
return (FALSE);
Depth_Stack = open_istack ();
if (All_Intersections (Object, Ray, Depth_Stack))
{
while ((Local = pop_entry(Depth_Stack)) != NULL)
if (Local->Depth < Closest)
{
*Ray_Intersection = *Local;
Closest = Local->Depth;
}
close_istack (Depth_Stack);
return (TRUE);
}
else
{
close_istack (Depth_Stack);
return (FALSE);
}
}
int Ray_In_Bounds (Ray,Bounds)
RAY *Ray;
OBJECT *Bounds;
{
OBJECT *Bound;
INTERSECTION Local;
for (Bound = Bounds;
Bound != NULL;
Bound = Bound->Sibling)
{
Bounding_Region_Tests++;
if (!Intersection (&Local, Bound, Ray))
if (!Inside_Object(&Ray->Initial,Bound))
return (FALSE);
Bounding_Region_Tests_Succeeded++;
}
return (TRUE);
}
int Point_In_Clip (IPoint, Clip)
VECTOR *IPoint;
OBJECT *Clip;
{
OBJECT *Local_Clip;
for (Local_Clip = Clip;
Local_Clip != NULL;
Local_Clip = Local_Clip->Sibling)
{
Clipping_Region_Tests++;
if (!Inside_Object(IPoint, Local_Clip))
return (FALSE);
Clipping_Region_Tests_Succeeded++;
}
return (TRUE);
}
OBJECT *Copy_Bound_Clip (Old)
OBJECT *Old;
{
OBJECT *Current, *New, *Prev, *First;
First = Prev = NULL;
for (Current = Old;
Current != NULL ;
Current = Current->Sibling)
{
New = Copy_Object (Current);
if (First == NULL)
First = New;
if (Prev != NULL)
Prev->Sibling = New;
Prev = New;
}
return (First);
}
OBJECT *Copy_Object (Old)
OBJECT *Old;
{
OBJECT *New;
if (Old == NULL)
return (NULL);
New = Copy (Old);
/* The following copying of OBJECT_FIELDS is redundant if Copy
did *New = *Old but we cannot assume it did.
It is safe for Copy to do *New = *Old but it should not otherwise
touch OBJECT_FIELDS. */
New->Methods = Old->Methods;
New->Type = Old->Type;
New->Sibling = Old->Sibling;
New->Texture = Old->Texture;
New->Bound = Old->Bound;
New->Clip = Old->Clip;
New->Bounds = Old->Bounds;
New->No_Shadow_Flag = Old->No_Shadow_Flag;
New->Sibling = NULL; /* Important */
New->Texture = Copy_Textures (Old->Texture);
New->Bound = Copy_Bound_Clip (Old->Bound);
if (Old->Bound != Old->Clip)
New->Clip = Copy_Bound_Clip (Old->Clip);
else
New->Clip = New->Bound;
return (New);
}
void Translate_Object (Object, Vector)
OBJECT *Object;
VECTOR *Vector;
{
OBJECT *Sib;
if (Object == NULL)
return;
for (Sib = Object->Bound;
Sib != NULL;
Sib = Sib->Sibling)
Translate_Object (Sib, Vector);
if (Object->Clip != Object->Bound)
for (Sib = Object->Clip;
Sib != NULL;
Sib = Sib->Sibling)
Translate_Object (Sib, Vector);
Translate_Textures (Object->Texture,Vector);
Translate (Object,Vector);
}
void Rotate_Object (Object, Vector)
OBJECT *Object;
VECTOR *Vector;
{
OBJECT *Sib;
if (Object == NULL)
return;
for (Sib = Object->Bound;
Sib != NULL;
Sib = Sib->Sibling)
Rotate_Object (Sib, Vector);
if (Object->Clip != Object->Bound)
for (Sib = Object->Clip;
Sib != NULL;
Sib = Sib->Sibling)
Rotate_Object (Sib, Vector);
Rotate_Textures (Object->Texture,Vector);
Rotate (Object,Vector);
}
void Scale_Object (Object, Vector)
OBJECT *Object;
VECTOR *Vector;
{
OBJECT *Sib;
if (Object == NULL)
return;
for (Sib = Object->Bound;
Sib != NULL;
Sib = Sib->Sibling)
Scale_Object (Sib, Vector);
if (Object->Clip != Object->Bound)
for (Sib = Object->Clip;
Sib != NULL;
Sib = Sib->Sibling)
Scale_Object (Sib, Vector);
Scale_Textures (Object->Texture,Vector);
Scale (Object,Vector);
}
int Inside_Object (IPoint, Object)
VECTOR *IPoint;
OBJECT *Object;
{
OBJECT *Sib;
/* removed 7/19/92 CEY
for (Sib = Object->Bound;
Sib != NULL;
Sib = Sib->Sibling)
if (!Inside_Object(IPoint, Sib))
return(FALSE);
*/
for (Sib = Object->Clip;
Sib != NULL;
Sib = Sib->Sibling)
if (!Inside_Object(IPoint, Sib))
return(FALSE);
return (Inside(IPoint,Object));
}
void Invert_Object (Object)
OBJECT *Object;
{
/* OBJECT *Sib; */
if (Object == NULL)
return;
/* removed 3/29/93 CEY
for (Sib = Object->Clip;
Sib != NULL;
Sib = Sib->Sibling)
Invert_Object (Sib);
*/
Invert (Object);
}
void Destroy_Object (Object)
OBJECT *Object;
{
OBJECT *Sib;
while (Object != NULL)
{
Destroy_Textures (Object->Texture);
Destroy_Object (Object->Bound);
if (Object->Bound != Object->Clip)
Destroy_Object (Object->Clip);
Sib = Object->Sibling;
Destroy(Object);
Object = Sib;
}
}
void Transform_Object (Object, Trans)
OBJECT *Object;
TRANSFORM *Trans;
{
OBJECT *Sib;
if (Object == NULL)
return;
for (Sib = Object->Bound;
Sib != NULL;
Sib = Sib->Sibling)
Transform_Object (Sib, Trans);
if (Object->Clip != Object->Bound)
for (Sib = Object->Clip;
Sib != NULL;
Sib = Sib->Sibling)
Transform_Object (Sib, Trans);
Transform_Textures (Object->Texture,Trans);
Transform (Object,Trans);
}
void create_istack ()
{
ISTACK *New;
if ((New = (ISTACK *) malloc (sizeof (ISTACK))) == NULL)
{
fprintf (stderr, "\nOut of memory. Cannot allocate istack");
close_all();
exit(1);
}
New->next = free_istack;
free_istack = New;
if ((New->istack = (INTERSECTION *)
malloc (Max_Intersections * sizeof (INTERSECTION))) == NULL)
{
fprintf (stderr, "\nOut of memory. Cannot allocate istack entries");
close_all();
exit(1);
}
Number_of_istacks++;
}
ISTACK *open_istack()
{
ISTACK *istk;
if (free_istack == NULL)
create_istack ();
istk = free_istack;
free_istack = istk->next;
istk->top_entry = 0;
return (istk);
}
void close_istack (istk)
ISTACK *istk;
{
istk->next = free_istack;
free_istack = istk;
}
void incstack(istk)
ISTACK *istk;
{
if (++istk->top_entry >= (unsigned int)Max_Intersections)
{
istk->top_entry--;
Istack_overflows++;
}
}